package com.demo.config.mq.handler;

import com.alibaba.fastjson.JSON;
import com.demo.config.mq.handler.dto.TgMessageDto;
import com.demo.config.mq.service.TgBotOneService;
import com.rabbitmq.client.Channel;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.Argument;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Slf4j
@Component
public class TgBotOneMqDelayHandler {

  @Autowired
  private TgBotOneService tgBotOneService;

  @RabbitListener(bindings = @QueueBinding(
      value = @Queue(value = TgBotOneMqConsts.BOT_ONE_DELAY_QUEUE, durable = "true"),
      exchange = @Exchange(name = TgBotOneMqConsts.BOT_ONE_DELAY_MODE_QUEUE,
          durable = "true",
          type = "x-delayed-message",
          ignoreDeclarationExceptions = "true"),
      key = TgBotOneMqConsts.BOT_ONE_DELAY_QUEUE,
      arguments ={@Argument(name = "x-delayed-type",value = "direct")}
  )
  )
  @RabbitHandler
  public void onMessage(Message message, Channel channel, TgMessageDto tgMessageDto){
    log.info("1号机器人延迟队列接收到消息:{}", JSON.toJSONString(tgMessageDto));
    MessageProperties messageProperties = message.getMessageProperties();
    long deliveryTag = messageProperties.getDeliveryTag();
    log.info("1号机器人延迟队列deliveryTag:" + deliveryTag);
    try {
      tgBotOneService.handler(tgMessageDto);
      channel.basicAck(deliveryTag, false);
      log.info("1号机器人延迟队列签收完成...{}", deliveryTag);
    }catch (IOException e) {
      //网络中断
      // 退回 requeue=false 丢弃， requeue=true 发回服务器，服务器重新入队
      excetionHandler(channel,deliveryTag, e, "网络问题异常");
    }catch (Exception e1){
      excetionHandler(channel,deliveryTag, e1, "系统异常");
    }
  }

  public void excetionHandler(Channel channel, long deliveryTag, Exception e, String errorMsg){
    //网络中断
    log.error("errorMsg:{}",errorMsg);
    log.error("Exception",e);
    // 退回 requeue=false 丢弃， requeue=true 发回服务器，服务器重新入队
    try{
      channel.basicNack(deliveryTag, false, true);
    }catch (Exception e1){
      log.error("1号机器人延迟队列消息重新入队异常deliveryTag:{}",deliveryTag);
      log.error("ERROR Exception",e);
    }
  }
}
